//===================================
//File: Test.cpp
//Main module
//Name: Smirnova O.P.
//Date: 28.06.12, v.1.0
//===================================

#include "MList.h"
#include "MListEl.h"
#include "Place.h"
#include "List.h"
#define MAX_VALUE 1000
#define MIN_VALUE -1000
#include "stdio.h"
#include <iostream>
#include "math.h"

using namespace std;

double addDouble(const char* msg, const int min_value = MIN_VALUE, const int max_value = MAX_VALUE){
    double res;
    cout<<msg;
    cin>> res;
    while (res<min_value || res>max_value)
    {
    	cout<<"Input value is not correct.\n";
    	cout<<"correct diap of value is [" << min_value << ";" << max_value << "]\n";
    	cin >> res;
    };
    return res;
       
}       
Point addPoint()
{
	double x;
	double y;
	Point P;
	do {
	cout << "Input x coord: ";
	cin  >> x;
	if (x < MIN_VALUE || x > MAX_VALUE)
	   cout << " Value must be in range "
		<< "MIN_VALUE " << MIN_VALUE << " MAX_VALUE " << MAX_VALUE << "\n\n";
	}
	 while (x < MIN_VALUE || x > MAX_VALUE);

	do
	{
	  cout << " Input y coord: ";
	  cin  >> y;
	  if (y < MIN_VALUE || y > MAX_VALUE)
	   cout << " Value must be in range "
		<< "MIN_VALUE " << MIN_VALUE << " MAX_VALUE " << MAX_VALUE << "\n\n";
	} while (y < MIN_VALUE || y > MAX_VALUE);
	P=Point(x,y,0);
	return P;
};
Body addBody()
{
	Body body;
	double h,b,c = 0.0;
	Point P5;
	system("clear");
	P5 = addPoint();
	h = addDouble("Input height of body\n", 1);
	b = addDouble("Input length of smaller base of body\n");
	c = b * 2.0;
    body = Body(P5, h, b, c);
    return body;
}
Throat addThroat(Body body)
{
	Point C = body.getTrapeze().getPointC();
	Point D = body.getTrapeze().getPointD();
	double b = abs(C.getX() - D.getX());
	double a = b / 2.0;
	Point T = Point(D.getX(), D.getY() - a, 0);
    Throat throat = Throat(T, a, b);
	
	return throat;
}
Tube addTube(Body body, Throat throat)
{
     double throat_width = throat.getRect().getB();
     double bulb_height = throat.getRect().getA() + body.getTrapeze().getH();
     double tube_width = throat_width / 20.0;
     double tube_height = bulb_height * 2.0;
     Point T = Point(body.getTrapeze().getPointC().getX() - throat_width / 2.0 - tube_width / 2.0,
		     body.getTrapeze().getPointA().getY() - tube_height, 0);
     Tube tube = Tube(T, tube_height, tube_width);
     return tube;
}
SpecImage* addImage()
{
	Body body = addBody();
	Throat throat = addThroat(body);
	Tube tube = addTube(body, throat);
    SpecImage *image = new SpecImage(tube, body, throat);
	return image;
}

void showImage(Image i)
{
	double h,a;
	Point P1,P2,P3,P4,P5,P6,P7,P8;
	Body body=i.getBody();
	Throat throat= i.getThroat();
	P1 = body.getTrapeze().getPointA();
	P2 = body.getTrapeze().getPointB();
	P3 = body.getTrapeze().getPointC();
	P4 = body.getTrapeze().getPointD();
	P5 = throat.getRect().getPointE();
	P6 = throat.getRect().getPointF();
	P7 = throat.getDistance().getPointE1();
	P8 = throat.getDistance().getPointF1();
	h=body.getTrapeze().getH();
	h += throat.getRect().getA();
	system("clear");
	cout<<"Height of bulb: "<<h<<endl;
	a=throat.getRect().getB() * 2;
	cout<<"Length of bottom of bulb: "<<a<<endl;
	system("clear");
	cout<<"List of points:";
	//List<Point> *list=;
	i.getPoints()->writeList();
	system("clear");
};
void showCollection(Placement *p)
{
	Collection c = p->getCollection();
	MultiList<Image> *col= c.getCollection();
	MultiListElem<Image> * temp = col->getRootListA();
	MultiListElem<Image> * head = col->getRootListA();
	if (temp == 0)
		cout<<"List is empty";
	else
	
	    do
	    {
		  Image i=temp->getValue();
		  showImage(i);
		  i.getID();
		  temp=temp->getElema();
	    }while (head != temp);
	cout<<endl;
};
void printTitle()
{
   system("clear");
   cout
	<< "Lab3" <<endl
  << "Building classes using simple inherit and multiply inherit" <<endl
	<< "Author: Smirnova O.P." <<endl
	<< "Date: 28.06.12 Version: 1.0" <<endl;
};

//Ввод XY
void inputXY(double &_x,double &_y)
{
       do
	     {
	       cout << " Input x: ";
	       cin  >> _x;
	       if (_x < MIN_VALUE || _x > MAX_VALUE)
	       cout << "Input value from diap"
		      << "MIN_VALUE" << MIN_VALUE << " MAX_VALUE" << MAX_VALUE << endl <<endl;
	     } while (_x < MIN_VALUE || _x > MAX_VALUE);

	     do
	     {
	       cout << " Input y: ";
	       cin  >> _y;
	       if (_y < MIN_VALUE || _y > MAX_VALUE)
	       cout << "Input value from diap"
		      << "MIN_VALUE" << MIN_VALUE << " MAX_VALUE" << MAX_VALUE << endl <<endl;
	     } while (_y < MIN_VALUE || _y > MAX_VALUE);
}

//Тестирование Набора
void testCollection(Placement *p)
{
char choice;
char enter;
double x,y;
int height, width;
short isI = 0;
cout<<"Input params for shelf:\n";
    cout<<"Height=  "; 
	cin>>height;
	cout<<"Width=  "; 
	cin>>width;
    cout<<"x = "; 
	cin>>x;
    cout<<"y=  "; 
	cin>>y;
    p= new Placement(Point(x,y,0),width,height);

while (1)
{
    system("clear");
	cout<<("--------------------Menu----------------------\n");
	cout<<("1:  Add PImage\n");
	cout<<("2:  move dxdy PImage\n");
	cout<<("3:  Show placement on shelf\n");
	cout<<("4:  Move dxdy shelf\n");
	cout<<("5:  Move shelf to point\n");
	cout<<("6:  Move shelf dxdy with PImage\n");
	cout<<("7:  Show shelf\n");
	cout<<("8: Remove all PImage\n");
	//cout<<("11:  Статистика классов\n");
	cout<<("9:  Exit\n");
	cout<<("----------------------------------------------\n\n");
	cout<<"Choose action: ";

	cin>>choice;
	switch(choice)
	{
		case '1':  {
			Image *image = addImage();
			p->getCollection()->addElem(*image);
			isI = 1;
				   } break;
			case '2':  {
							   if(isI==0) 
					   cout << "Collection is empty\n";
							   else
							   {
				cout<<"Input point for movedxdy images:";
				inputXY(x,y);
				p->Collection::moveTodXdY(x,y);
				
                MultiListElem<Image>* temp = p->getCollection()->getRootListA();
                MultiListElem<Image>* head = p->getCollection()->getRootListA();
			 
				int number=1;
			 if (isI > 0)
				//if Collection not empty
             do
	{
		Image s1 = temp->getValue();
		if (p->isVisible(s1)==1)
		{
        temp=temp->getElema();
		number++;
		continue;}
		else {
			cout<<"Perfect_Image with ID= "<<s1.getID()<<" out of shelf."<<endl;
			temp=temp->getElema();
			}
		   }while(head != temp);
							   }
				   } break;
		case '3':  {
						   if(isI==0) 
					   cout << "Collection is empty";
						   else
			p->Collection::writeList();
	       
				   } break;
		case '4':  {
			 cout<<"Input point for movedxdy shelf:";
			 inputXY(x,y);     
			 p->moveShelfTodXdY(x,y);
				MultiListElem<Image>* temp = p->getCollection()->getRootListA();
			    MultiListElem<Image>* head = p->getCollection()->getRootListA();
				int number=1;
			 if (isI > 0)
				//if Collection not empty
             do
	{
		Image s1 = temp->getValue();
		if (p->isVisible(s1)==1)
		{temp=temp->getElema();
		number++;
		continue;}
		else {
			cout<<"Perfect_Image with ID= "<<s1.getID()<<" out of shelf."<<endl;
			temp=temp->getElema();
			}
		   }while (head != temp);
				   } break;
		case '5':  {
			      cout<<"Input point for move shelf:";    
			 p->moveShelfToPoint(addPoint());
				 MultiListElem<Image>* temp = p->getCollection()->getRootListA();
			     MultiListElem<Image>* head = p->getCollection()->getRootListA();
				int number=1;
				if (isI > 0)
				//if Collection not empty
			 do
	{
		Image s1 = temp->getValue();
		if (p->isVisible(s1)==1)
		{temp=temp->getElema();
		number++;
		continue;}
		else {
			cout<<"Perfect_Image with ID= "<<s1.getID()<<" out of shelf."<<endl;
			temp=temp->getElema();
			}
		   }while(head != temp);
				   }; break;
		case '6':  {
			      cout<<"Input point for movedxdy shelf with images:";    
				   inputXY(x,y);   

				   p->moveAll(x,y);
				 MultiListElem<Image>* temp = p->getCollection()->getRootListA();
                 MultiListElem<Image>* head = p->getCollection()->getRootListA();
				int number=1;
			 if (isI > 0)
				//if Collection not empty
             do
	{
		Image s1 = temp->getValue();
		if (p->isVisible(s1)==1)
		{temp=temp->getElema();
		number++;
		continue;}
		else {
			cout<<"Perfect_Image with ID= "<<s1.getID()<<" out of shelf."<<endl;
			temp=temp->getElema();
           }
		   }while (head != temp);
				   }; break;
		case '7':  {
			      cout<<"Shelf:" << endl;
				  p->write();
				   }; break;
		case '8':  {
			isI = 0;

			break;
				   };
		case '9': return;
			
	   default:cout<<"You input incorrect value , try again"<<endl;break;
				   };
				   
	}
};
int main()
{
printTitle();
Placement *c = 0;

 testCollection(c);
 return 0;
}
